<template>
    <div ref='canvas_wrap' :style='{background: background}' class='canvas_wrap'>
        <canvas ref='canvas_3d' class='canvas_3d'></canvas>
    </div>
</template>

<script>
import { AutoUnevent } from '@/utils/utilFun.js';

const event = new AutoUnevent();
export default {
    props: {
        list: {
            type: Array,
            required: true,
            default: () => [],
        },
        background: {
            type: String,
            default: () => '#bcbcbc',
        },
    },
    data() {
        return {
            imageCache: [],
            // 颜色应该是动态的
            scale: 1,
            ratio: 1,
            currentIframe: 0,
            position: {
                x: 0,
                y: 0,
            },
            _ctx: null,
        };
    },
    async mounted() {
        await this.reload();
        const canvas_wrap = this.$refs['canvas_wrap'];
        var canvas = this.$refs['canvas_3d'];
        var startx = null,
            endx = null;
        var moveIframe = event => {
            endx = event.clientX || event.touches[0].pageX;
            if (endx - startx > 1) {
                this.currentIframe++;
            } else if (endx - startx < -1) {
                this.currentIframe--;
            }
            this.draw();
            startx = endx;
        };

        const wrap = document.getElementsByClassName('canvas_wrap')[0];
        event.on(
            wrap,
            'mousedown',

            function(e) {
                startx = e.clientX;
                event.on(wrap, 'mousemove', moveIframe, {
                    passive: false,
                });
            },
            {
                passive: false,
            }
        );

        event.on(
            wrap,
            'mouseup',
            function() {
                startx = null;
                endx = null;
                event.off(wrap, 'mousemove', moveIframe, {
                    passive: false,
                });
            },
            {
                passive: false,
            }
        );
        event.on(
            wrap,
            'touchstart',
            function(e) {
                startx = e.touches[0].pageX;
                event.on(wrap, 'touchmove', moveIframe, {
                    passive: false,
                });
            },
            {
                passive: false,
            }
        );
        event.on(
            wrap,
            'touchend',
            function() {
                startx = null;
                endx = null;
                event.off(wrap, 'touchmove', moveIframe, {
                    passive: false,
                });
            },
            {
                passive: false,
            }
        );
        event.on(
            window,
            'resize',
            () => {
                const offsetWidth = canvas_wrap.offsetWidth;
                const offsetHeight = canvas_wrap.offsetHeight;
                canvas.width = offsetWidth; // - (innerWidth - offsetWidth);
                canvas.height = offsetHeight; // - (innerHeight - offsetHeight);
                this.draw();
            },
            {
                passive: true,
            }
        );
    },
    methods: {
        loadImage() {
            let count = 0;
            this.imageCache = [];
            return new Promise((resolve, reject) => {
                this.list.forEach((item, index) => {
                    const img = new Image();
                    img.onload = () => {
                        this.imageCache[index] = img;
                        count++;
                        if (count >= this.list.length) {
                            setTimeout(() => {
                                this.$emit('loading', count, this.list.length);
                            }, 300);
                            resolve();
                            return;
                        }
                        this.$emit('loading', count, this.list.length);
                    };
                    img.onerror = () => {
                        count++;
                        this.$emit('loading', count, this.list.length);
                    };
                    img.src = item;
                });
            });
        },
        async reload() {
            await this.loadImage();
            var canvas = this.$refs['canvas_3d'];
            const canvas_wrap = this.$refs['canvas_wrap'];
            var ctx = canvas.getContext('2d');
            this._ctx = ctx;
            var devRatio = window.devicePixelRatio || 1,
                backingStore =
                    ctx.backingStorePixelRatio ||
                    ctx.webkitBackingStorePixelRatio ||
                    ctx.mozBackingStorePixelRatio ||
                    ctx.msBackingStorePixelRatio ||
                    ctx.oBackingStorePixelRatio ||
                    ctx.backingStorePixelRatio ||
                    1;

            canvas.width = canvas_wrap.offsetWidth;
            canvas.height = canvas_wrap.offsetHeight;
            this.ratio = this.imageCache[0].height / this.imageCache[0].width;
            this.draw();
        },
        draw() {
            var canvas = this.$refs['canvas_3d'];
            if (this.currentIframe < 0) {
                this.currentIframe = this.imageCache.length - 1;
            }
            this.currentIframe = this.currentIframe % this.imageCache.length;
            this._ctx.clearRect(0, 0, canvas.width, canvas.height);
            if (canvas.height / canvas.width > this.ratio) {
                this._ctx.drawImage(
                    this.imageCache[this.currentIframe],
                    (canvas.width * (1 - this.scale)) / 2.0 + this.position.x,
                    (canvas.height - canvas.width * this.ratio * this.scale) / 2.0 + this.position.y,
                    canvas.width * this.scale,
                    canvas.width * this.ratio * this.scale
                );
            } else {
                this._ctx.drawImage(
                    this.imageCache[this.currentIframe],
                    (canvas.width - (canvas.height * this.scale) / this.ratio) / 2 + this.position.x,
                    (canvas.height * (1 - this.scale)) / 2.0 + this.position.y,
                    (canvas.height * this.scale) / this.ratio,
                    canvas.height * this.scale
                );
            }
        },
        offset(x, y, isCount) {
            if (typeof x === 'number') {
                if (isCount) {
                    this.position.x += x;
                } else {
                    this.position.x = x;
                }
            }
            if (typeof y === 'number') {
                if (isCount) {
                    this.position.y += y;
                } else {
                    this.position.y = y;
                }
            }
            this.draw();
        },
        strainScale(a) {
            if (this.scale + a <= 0.2 || Math.floor(this.scale + a) > 2) {
                return;
            }
            this.scale += a;
            this.draw();
        },
        nextImage(next = 1) {
            this.currentIframe = (this.imageCache.length + this.currentIframe + next) % this.imageCache.length;
            this.draw();
        },
    },
    watch: {
        list: function() {
            this.reload();
        },
    },
    beforeDestroy() {
        event.clear();
    },
};
</script>
<style lang="scss" scoped>
.canvas_wrap {
    display: inline-block;
    position: relative;
    width: 100%;
    height: 100%;

    .canvas_3d {
        position: absolute;
        left: 50%;
        top: 50%;
        transform: translate(-50%, -50%);
    }
}
</style>